﻿// Copyright 2013 Ronald Schlenker, www.technewlogic.de.
// 
// This file is part of Byond.
// 
// Byond is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
// 
// Byond is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Byond.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Windows.Threading;
using Utils.CtorSubstitution;

namespace Utils.DialogManagement
{
	public class DialogManager : IDialogManager
	{
		public DialogManager(Lazy<IDialogHost> parent)
		{
			_dialogLayeringHelper = new Lazy<DialogLayeringHelper>(
				() => new DialogLayeringHelper(parent.Value));
		}

		private readonly UiDispatcher _dispatcher;
		private readonly Lazy<DialogLayeringHelper> _dialogLayeringHelper;

		#region Implementation of IDialogManager

		public IMessageDialog CreateMessageDialog(string message, DialogMode dialogMode)
		{
			IMessageDialog dialog = null;
			InvokeInUiThread(() =>
				{
					dialog = new MessageDialog(_dialogLayeringHelper.Value, dialogMode, message, _dispatcher);
				});
			return dialog;
		}

		public IMessageDialog CreateMessageDialog(string message, string caption, DialogMode dialogMode)
		{
			IMessageDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = new MessageDialog(_dialogLayeringHelper.Value, dialogMode, message, _dispatcher)
				{
					Caption = caption
				};
			});
			return dialog;
		}

		public IInputDialog CreateInputDialog(string message, DialogMode dialogMode)
		{
			IInputDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = new InputDialog(_dialogLayeringHelper.Value, dialogMode, message, _dispatcher);
			});
			return dialog;
		}

		public IInputDialog CreateInputDialog(string message, string caption, DialogMode dialogMode)
		{
			IInputDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = new InputDialog(_dialogLayeringHelper.Value, dialogMode, message, _dispatcher)
				{
					Caption = caption
				};
			});
			return dialog;
		}

		public IProgressDialog CreateProgressDialog(DialogMode dialogMode)
		{
			IProgressDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = WaitProgressDialog.CreateProgressDialog(_dialogLayeringHelper.Value, dialogMode, _dispatcher);
				dialog.CloseWhenWorkerFinished = true;
			});
			return dialog;
		}

		public IProgressDialog CreateProgressDialog(string message, DialogMode dialogMode)
		{
			IProgressDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = WaitProgressDialog.CreateProgressDialog(_dialogLayeringHelper.Value, dialogMode, _dispatcher);
				dialog.CloseWhenWorkerFinished = true;
				dialog.Message = message;
			});
			return dialog;
		}

		public IProgressDialog CreateProgressDialog(string message, string readyMessage, DialogMode dialogMode)
		{
			IProgressDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = WaitProgressDialog.CreateProgressDialog(_dialogLayeringHelper.Value, dialogMode, _dispatcher);
				dialog.CloseWhenWorkerFinished = true;
				dialog.ReadyMessage = readyMessage;
				dialog.Message = message;
			});
			return dialog;
		}

		public IWaitDialog CreateWaitDialog(DialogMode dialogMode)
		{
			IWaitDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = WaitProgressDialog.CreateWaitDialog(_dialogLayeringHelper.Value, dialogMode, _dispatcher);
				dialog.CloseWhenWorkerFinished = true;
			});
			return dialog;
		}

		public IWaitDialog CreateWaitDialog(string message, DialogMode dialogMode)
		{
			IWaitDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = WaitProgressDialog.CreateWaitDialog(_dialogLayeringHelper.Value, dialogMode, _dispatcher);
				dialog.CloseWhenWorkerFinished = true;
				dialog.Message = message;
			});
			return dialog;
		}

		public IWaitDialog CreateWaitDialog(string message, string readyMessage, DialogMode dialogMode)
		{
			IWaitDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = WaitProgressDialog.CreateWaitDialog(_dialogLayeringHelper.Value, dialogMode, _dispatcher);
				dialog.CloseWhenWorkerFinished = true;
				dialog.Message = message;
				dialog.ReadyMessage = readyMessage;
			});
			return dialog;
		}

		public ICustomContentDialog CreateCustomContentDialog(object content, DialogMode dialogMode)
		{
			ICustomContentDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = new CustomContentDialog(_dialogLayeringHelper.Value, dialogMode, content, _dispatcher);
			});
			return dialog;
		}

		public ICustomContentDialog CreateCustomContentDialog(object content, string caption, DialogMode dialogMode)
		{
			ICustomContentDialog dialog = null;
			InvokeInUiThread(() =>
			{
				dialog = new CustomContentDialog(_dialogLayeringHelper.Value, dialogMode, content, _dispatcher)
				{
					Caption = caption
				};
			});
			return dialog;
		}

		#endregion

		private void InvokeInUiThread(Action del)
		{
			_dispatcher.Invoke(del);
		}
	}
}